<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>closure</title>
</head>
<body>
  <script>
    function once (fn) {
      let flag = true
      return function () {
        if (flag) {
          flag = false
          return fn.apply(this, arguments)
        }
      }
    }

    const Person = function (name) {
      this.name = name
      this.pay = once(function (money) {
        console.log(`${this.name}支付${money}`)
      })
    }

    const zhangsan = new Person('张三')
    zhangsan.pay(5)
    zhangsan.pay(5)
    // const r = once(function (arg) {
    //   console.log(arg)
    // })

    function makeSalary (base) {
      return function (performance) {
        return base + performance
      }
    }
    let salaryLevel1 = makeSalary(12000)
    let salaryLevel2 = makeSalary(15000)

    console.log(salaryLevel1(3000))
    console.log(salaryLevel1(5000))
    console.log(salaryLevel2(5000))
    

    /* 首先函数声明比变量要高， 其次 b = 20 没有 var ， 说明是 window 最
    外层定义的变量。
    js 作用域中， 先找最近的 那就是 b fn ， 直接打印了， 如果 b = 20 有 var 那就是
    打印 20 */
    var b = 10; 
    (function b() {
      b = 20
      console.log(b)
    })();
    // (function c() {
    //   b = 20
    //   console.log(b)
    // })();
    console.log(b)

    // 模拟curry
    function curry (fn) {
      const fnLen = fn.length
      return function _curry (...args) {
        if (args.length < fnLen) {
          return function () {
            return _curry(...args.concat(Array.from(arguments)))
          }
        }
        return fn(...args)
      }
    }
    const match = curry(function (reg, str) {
      return str.match(reg)
    })
    const haveSpace = match(/\s+/g)
    const haveNumber = match(/\d+/g)
    const filter = curry(function (fn, arr) {
      return arr.filter(fn)
    })
    const findSpace = filter(haveSpace)
    console.log(findSpace(['d_ddd', 'd dd']))
  </script>
</body>
</html>